package com.lscdu.gulimall.ruoyi_springboot.service.impl;

import com.lscdu.gulimall.ruoyi_springboot.bean.login.LoginBody;
import com.lscdu.gulimall.ruoyi_springboot.bean.login.LoginUser;
import com.lscdu.gulimall.ruoyi_springboot.bean.login.SysUser;
import com.lscdu.gulimall.ruoyi_springboot.common.core.redis.RedisCache;
import com.lscdu.gulimall.ruoyi_springboot.service.ISysConfigService;
import com.lscdu.gulimall.ruoyi_springboot.service.ISysUserService;
import com.lscdu.gulimall.ruoyi_springboot.service.SysLoginService;
import com.lscdu.gulimall.ruoyi_springboot.service.TokenService;
import com.lscdu.gulimall.ruoyi_springboot.utis.DateUtils;
import com.lscdu.gulimall.ruoyi_springboot.utis.IpUtils;
import com.lscdu.gulimall.ruoyi_springboot.utis.StringUtils;
import com.lscdu.gulimall.ruoyi_springboot.utis.constant.CacheConstants;
import com.lscdu.gulimall.ruoyi_springboot.utis.security.AuthenticationContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author 啊昌
 * @date 2024/9/9 11:33
 * SysLoginServiceimpl
 */

@Service
public class SysLoginServiceimpl implements SysLoginService {


	@Autowired
	private ISysUserService userService;

	@Autowired
	private ISysConfigService configService;

	@Autowired
	private RedisCache redisCache;
	@Resource
	private AuthenticationManager authenticationManager;

	@Autowired
	private TokenService tokenService;


	@Override
	public String login(LoginBody loginBody) {
		//1.验证码校验
		validateCaptcha(loginBody.getUsername(), loginBody.getCode(), loginBody.getUuid());
		//2. todo 登录前置校验
		loginPreCheck(loginBody.getUsername(),loginBody.getPassword());
		//todo 用户校验 spring Security 验证
		Authentication authentication = null;
		try {
			UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginBody.getUsername(), loginBody.getPassword());
			AuthenticationContextHolder.setContext(authenticationToken);
			// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername 完成用户的登录验证
			authentication = authenticationManager.authenticate(authenticationToken);
		} finally {
			//  清除线程
			AuthenticationContextHolder.clearContext();
		}
		//获取用户的登录信息
		LoginUser loginUser = (LoginUser) authentication.getPrincipal();
		recordLoginInfo(loginUser.getUserId());
		//生成token
		return  tokenService.createToken(loginUser);
	}


	/**
	 * 记录登录信息
	 *
	 * @param userId 用户ID
	 */
	private void recordLoginInfo(Long userId) {
		SysUser sysUser = new SysUser();
		sysUser.setUserId(userId);
		sysUser.setLoginIp(IpUtils.getIpAddr()); // 获取到登录的IP
		sysUser.setLoginDate(DateUtils.getNowDate()); //更新登录的时间
		userService.updateUserProfile(sysUser);  //更新 用户
	}

	/**
	 * 登录前置校验
	 *
	 * @param username 用户名
	 * @param password 用户密码
	 */
	private void loginPreCheck(String username, String password) {

	}


	/**
	 * 校验验证码
	 *
	 * @param username 用户名
	 * @param code     验证码
	 * @param uuid     唯一标识
	 * @return 结果
	 */
	private void validateCaptcha(String username, String code, String uuid) {
		boolean captchaEnabled = configService.selectCaptchaEnabled();
		if (captchaEnabled) {
			// 开启了验证码
			//缓存在redis 的key 也就是验证码的答案
			String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
			String captcha = redisCache.getCacheObject(verifyKey);
			if (captcha == null) {
				// todo 验证码 ==null 则抛出异常
			}
			// redis 删除缓存的code
			redisCache.deleteObject(verifyKey);
			//校验验证码
			if (!code.equalsIgnoreCase(verifyKey)) {
				// todo 验证码不相等 则抛出异常
			}
		}
	}
}
